package com.wg.net;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.wg.net.exception.NetServiceException;
import com.wg.net.server.http.HttpServer;
import com.wg.net.server.tcp.TcpServer;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 网络服务核心管理类（统一管理HTTP/TCP服务器的生命周期与状态）
 * <p>
 * 职责：
 * - 封装HTTP/TCP服务器的初始化、启动、关闭操作
 * - 管理服务器运行状态（防止重复启动/关闭）
 * - 提供服务器实例访问接口（支持业务层扩展）
 * - 统一异常处理与日志记录
 *
 * @author 少爷123
 */
public class NetService {
    private static final Log log = LogFactory.get();
    private static final NetService INSTANCE = new NetService();

    private volatile HttpServer httpServer;
    private volatile TcpServer tcpServer;

    private final AtomicBoolean isInitialized = new AtomicBoolean(false);
    private final AtomicBoolean isShutdown = new AtomicBoolean(false);

    private NetService() {
    }

    /**
     * 获取网络服务单例实例
     *
     * @return NetService 单例对象
     */
    public static NetService getInstance() {
        return INSTANCE;
    }

    /**
     * 初始化网络服务（启动HTTP/TCP服务器）
     * <p>
     * 流程：
     * 1. 检查初始化状态（防止重复初始化）
     * 2. 加载网络配置（端口、线程数等）
     * 3. 启动HTTP服务器（若有配置）
     * 4. 启动TCP服务器（若有配置）
     *
     * @throws NetServiceException 初始化失败时抛出（包含具体错误原因）
     */
    public void init() throws NetServiceException {
        if (!isInitialized.compareAndSet(false, true)) {
            log.warn("网络服务已初始化，无需重复操作");
            return;
        }

        try {
            NetConfig netConfig = NetConfig.getInstance();

            // 启动HTTP服务器
            if (netConfig.getHttpPort() > 0) {
                httpServer = new HttpServer(netConfig);
                httpServer.start();
            }

            // 启动TCP服务器
            if (netConfig.getTcpPort() > 0) {
                tcpServer = new TcpServer(netConfig);
                tcpServer.start();
            }

            log.info("网络服务初始化完成");
        } catch (Exception e) {
            isInitialized.set(false);
            throw new NetServiceException("网络服务初始化失败", e);
        }
    }

    /**
     * 关闭网络服务（优雅停止HTTP/TCP服务器）
     * <p>
     * 流程：
     * 1. 检查关闭状态（防止重复关闭）
     * 2. 停止TCP服务器（若有实例）
     * 3. 停止HTTP服务器（若有实例）
     * 4. 标记服务为已关闭
     */
    public void shutdown() {
        if (!isShutdown.compareAndSet(false, true)) {
            log.warn("网络服务已关闭，无需重复操作");
            return;
        }

        try {
            // 停止TCP服务器
            if (tcpServer != null) {
                tcpServer.stop();
                log.info("TCP服务器已停止");
            }

            // 停止HTTP服务器
            if (httpServer != null) {
                httpServer.stop();
                log.info("HTTP服务器已停止");
            }

            // 清理资源
            httpServer = null;
            tcpServer = null;
            log.info("网络服务关闭完成");
        } catch (Exception e) {
            log.error("网络服务关闭异常", e);
        }
    }

    /**
     * 检查网络服务是否已初始化
     *
     * @return {@code true}：已初始化；{@code false}：未初始化或已关闭
     */
    public boolean isInitialized() {
        return isInitialized.get() && !isShutdown.get();
    }

    /**
     * 检查网络服务是否已关闭
     *
     * @return {@code true}：已关闭；{@code false}：未关闭或未初始化
     */
    public boolean isShutdown() {
        return isShutdown.get();
    }
}